import * as THREE from '../../build/three.module.js';

// 生成文本材质
const gemerateLabelMaterial = text => {
  const canvas = document.createElement('canvas');
  canvas.width = 128;
  canvas.height = 32;
  const ctx = canvas.getContext('2d');
  ctx.fillStyle = 'rgba(0, 0, 0, 0.95)';
  ctx.fillRect(0, 0, 128, 32);
  ctx.fillStyle = 'white';
  ctx.font = '12pt arial bold';
  ctx.fillText(text, 10, 22);
  const texture = new THREE.CanvasTexture(canvas);
  return new THREE.MeshBasicMaterial({ map: texture, transparent: true });
}

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(70, innerWidth / innerHeight, 1, 1000);
camera.position.z = 600;

// 背景
const canvas = document.createElement('canvas');
canvas.width = 128;
canvas.height = 128;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#ddd';
ctx.fillRect(0, 0, 128, 128);
ctx.fillStyle = '#555';
ctx.fillRect(0, 0, 64, 64);
ctx.fillStyle = '#999';
ctx.fillRect(32, 32, 32, 32);
ctx.fillStyle = '#555';
ctx.fillRect(64, 64, 64, 64);
ctx.fillStyle = '#777';
ctx.fillRect(96, 96, 32, 32);

const mapBg = new THREE.CanvasTexture(canvas);
mapBg.wrapS = mapBg.wrapT = THREE.RepeatWrapping;
mapBg.repeat.set(128, 64);

const materialBg = new THREE.MeshBasicMaterial({ map: mapBg });

const meshBg = new THREE.Mesh( new THREE.PlaneBufferGeometry(4000, 2000), materialBg );
meshBg.position.set(0, 0, -1);
scene.add(meshBg);

// 主体
// 5种混合模式
const blendings = [
  { name: 'No', constant: THREE.NoBlending },
  { name: 'Normal', constant: THREE.NormalBlending },
  { name: 'Additive', constant: THREE.AdditiveBlending },
  { name: 'Subtractive', constant: THREE.SubtractiveBlending },
  { name: 'Multipy', constant: THREE.MultiplyBlending }
];

// 主体贴图
const textureLoader = new THREE.TextureLoader();
const map0 = textureLoader.load( '../../textures/uv_grid_opengl.jpg' );
const map1 = textureLoader.load( '../../textures/sprite0.jpg' );
const map2 = textureLoader.load( '../../textures/sprite0.png' );
const map3 = textureLoader.load( '../../textures/lensflare/lensflare0.png' );
const map4 = textureLoader.load( '../../textures/lensflare/lensflare0_alpha.png' );

// 主体几何体
const geoMap = new THREE.PlaneBufferGeometry(100, 100);
const geoLabel = new THREE.PlaneBufferGeometry(100, 25);

// 创建主体网格体对象
const addImageRow = (map, y) => {
  for(let i = 0; i < blendings.length; i += 1) {
    const blending = blendings[i];

    // 创建材质
    const mat = new THREE.MeshBasicMaterial({ map: map });
    mat.transparent = true;
    mat.blending = blending.constant;

    // 定位
    const x = (i - blendings.length / 2) * 110;
    const z = 0;

    // 贴图网格体
    const meshMap = new THREE.Mesh(geoMap, mat);
    meshMap.position.set(x, y, z);
    scene.add(meshMap);

    // 标签网格体
    const meshLabel = new THREE.Mesh(geoLabel, gemerateLabelMaterial(blending.name));
    meshLabel.position.set(x, y - 75, z);
    scene.add(meshLabel);
  }
}

addImageRow( map0, 300 );
addImageRow( map1, 150 );
addImageRow( map2, 0 );
addImageRow( map3, - 150 );
addImageRow( map4, - 300 );

// 渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(devicePixelRatio);
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

// 事件处理
window.addEventListener('resize', () => {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(innerWidth, innerHeight);
}, false);

// 驱动动画
const animate = () => {
  requestAnimationFrame(animate);

  const time = Date.now() * 0.0003;
  const ox = (time * - 0.01 * mapBg.repeat.x) % 1;
  const oy = (time * - 0.01 * mapBg.repeat.y) % 1;
  
  mapBg.offset.set(ox, oy);

  renderer.render(scene, camera);
}
animate();